package cn.itcast.web.controller.cargo;


import cn.itcast.domain.cargo.*;
import cn.itcast.domain.system.User;
import cn.itcast.service.cargo.ContractService;
import cn.itcast.service.cargo.ExportProductService;
import cn.itcast.service.cargo.ExportService;
import cn.itcast.vo.ExportProductVo;
import cn.itcast.vo.ExportResult;
import cn.itcast.vo.ExportVo;
import cn.itcast.web.controller.BaseController;
import cn.itcast.web.utils.BeanMapUtils;
import com.alibaba.dubbo.config.annotation.Reference;
import com.github.pagehelper.PageInfo;
import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.apache.cxf.jaxrs.client.WebClient;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;

@Controller
@RequestMapping("/cargo/export")
public class ExportController extends BaseController {

    @Reference
    private ContractService contractService;

    @Reference
    private ExportService exportService;

    @Reference
    private ExportProductService exportProductService;

    /*
        url:/cargo/export/contractList.do
        作用：点击合同管理，进入可以报运的购销合同列表
                购销合同中State：0代表是草稿，不允许报运，1代表可以报运，2代表已经报运
        参数：
    */
    @RequestMapping("/contractList")
    public String list(@RequestParam(defaultValue  = "1") Integer pageNum,@RequestParam(defaultValue = "5") Integer pageSize){
        ContractExample contractExample = new ContractExample();
        contractExample.setOrderByClause("create_time desc");//desc 降序、 asc 升序

        contractExample.createCriteria().andStateEqualTo(1).andCompanyIdEqualTo(getLoginUserCompanyId());
        PageInfo<Contract> pageInfo = contractService.findByPage(contractExample, pageNum, pageSize);
        request.setAttribute("pageInfo",pageInfo);
        return "cargo/export/export-contractList";
    }

    /*
        url:/cargo/export/list.do
        作用：点击出口报运，进入报运单列表
        参数：
    */
    @RequestMapping("/list")
    public String findAll(@RequestParam(defaultValue  = "1") Integer pageNum,@RequestParam(defaultValue = "5") Integer pageSize){
        ExportExample exportExample = new ExportExample();
        exportExample.setOrderByClause("create_time desc");//desc 降序、 asc 升序
        exportExample.createCriteria().andCompanyIdEqualTo(getLoginUserCompanyId());
        PageInfo<Export> pageInfo = exportService.findByPage(exportExample, pageNum, pageSize);
        request.setAttribute("pageInfo",pageInfo);
        return "cargo/export/export-list";
    }

    /*
        url:/cargo/export/toCheckStatus.do
        作用：异步请求 根据勾选的购销合同id找其状态
        参数： 勾选的购销合同id  可以用String[] id接收  或者String id接收
        报运单的状态：  0-草稿 1-已上报 2(已报运可以装箱) 3-委托 4-发票 5-财务
        */
    @RequestMapping("/toCheckStatus")
    @ResponseBody
    public String toCheckStatus(String id){
        String[] ids = id.split(",");
        //根据ids查找报运单
        ExportExample exportExample = new ExportExample();
        exportExample.createCriteria().andIdIn(Arrays.asList(ids));
        List<Export> exportList = exportService.findAll(exportExample);
        if (exportList!=null){
            for (Export export : exportList) {
                if (2!=export.getState()){
                    return "false";
                }
            }
        }
        return "true";
    }

    /*
      url:/cargo/export/toPacking.do
      作用： （选择已报运的报运单）进入新增装箱页面
      参数： 购销合同id  可以用String[] id接收  或者String id接收
      报运单的状态：  0-草稿 1-已上报 2(已报运可以装箱) 3-委托 4-发票 5-财务
     */
    @RequestMapping("/toPacking")
    public String toPacking(String id){
        if (id==null){
            id="";
        }
        String[] ids = id.split(",");
        //根据ids查找报运单
        ExportExample exportExample = new ExportExample();
        exportExample.createCriteria().andIdIn(Arrays.asList(ids));
        List<Export> exportList = exportService.findAll(exportExample);
        //多个报运单的装运港、目的港、收货人如果不一致，不能合并报运单装箱，进入错误页面给与提示
        if (exportList!=null){
            for (int i = exportList.size()-1; i >= 0; i--) {
                for (int j = 0; j <= i-1; j++) {
                    //收货人
                    if (!exportList.get(i).getConsignee().equals(exportList.get(j).getConsignee())){
                        request.setAttribute("errorPacking","报运数据不一致，不能装箱！");
                        return "cargo/export/export-list";
                    }
                    //装船港
                    if (!exportList.get(i).getShipmentPort().equals(exportList.get(j).getShipmentPort())){
                        request.setAttribute("errorPacking","报运数据不一致，不能装箱！");
                        return "cargo/export/export-list";
                    }
                    //目的港
                    if (!exportList.get(i).getDestinationPort().equals(exportList.get(j).getDestinationPort())){
                        request.setAttribute("errorPacking","报运数据不一致，不能装箱！");
                        return "cargo/export/export-list";
                    }
                }
            }
        }
        //根据报运单的ids查找 合同号（拼接）；计算总体积、总毛重、总净重、装箱费用
        Packing packing = new Packing();
        if (exportList!=null){
            //合同号
            String exportNos = "";
            //总体积
            Double totalVolume = 0.00;
            //总毛重
            Double grossWeights = 0.00;
            //总净重
            Double netWeights = 0.00;

            for (Export export : exportList) {
                exportNos += export.getCustomerContract();
                totalVolume += export.getMeasurements();
            }

            ExportProductExample exportProductExample = new ExportProductExample();
            exportProductExample.createCriteria().andExportIdIn(Arrays.asList(ids));
            List<ExportProduct> exportProducts = exportProductService.findAll(exportProductExample);
            if (exportProducts!=null) {
                for (ExportProduct exportProduct : exportProducts) {
                    if (exportProduct.getGrossWeight() != null) {
                        grossWeights += exportProduct.getGrossWeight();
                    }
                    if (exportProduct.getNetWeight() != null) {
                        netWeights += exportProduct.getNetWeight();
                    }
                }
            }

            packing.setExportNos(exportNos);
            packing.setTotalVolume(totalVolume);
            packing.setGrossWeights(grossWeights);
            packing.setNetWeights(netWeights);
            //装箱费用
            packing.setPackingMoney(grossWeights*520);/*总毛重*520*/
        }

        request.setAttribute("packing",packing);
        request.setAttribute("id",id);
        return "cargo/export/export-toPacking";
    }

    /*
  url:/cargo/export/toExport.do
  作用： （选择要报运的购销合同进行报运）进入新增出口报运单页面
  参数： 购销合同id  可以用String[] id接收  或者String id接收
 */
    @RequestMapping("/toExport")
    public String toExport(String id){
        request.setAttribute("id",id);
        return "cargo/export/export-toExport";
    }

    /*
          url:/cargo/export/edit.do
          作用： 保存、修改 报运单信息
          参数： export
         */
    @RequestMapping("/edit")
    public String edit(Export export){
        //报运单的创建人
        export.setCreateBy(getLoginUser().getId());
        //报运单的创建人所属的部门
        export.setCreateDept(getLoginUser().getDeptId());
        //报运单的创建人所属的企业id
        export.setCompanyId(getLoginUserCompanyId());
        //报运单的创建人所属的企业名称
        export.setCompanyName(getLoginUserCompanyName());

        if (StringUtils.isEmpty(export.getId())){
            //如果id为空，添加报运单信息
            exportService.save(export);
        }else {
            //页面有传id，修改报运单信息  和页面的报运单商品信息
            exportService.update(export);
        }
        return "redirect:/cargo/export/list.do";
    }

    /*
      url:/cargo/export/toUpdate.do?id=92489126-480e-41d4-8918-7ffda46f52e1
      作用： 进入编辑页面,数据回显，通过id查找报运单信息、报运单的商品
      参数： 报运单id
     */
    @RequestMapping("/toUpdate")
    public String toUpdate(String id){
        Export export = exportService.findById(id);
        request.setAttribute("export",export);

        ExportProductExample exportProductExample = new ExportProductExample();
        exportProductExample.createCriteria().andExportIdEqualTo(id);
        List<ExportProduct> exportProductList = exportProductService.findAll(exportProductExample);
        request.setAttribute("eps",exportProductList);

        return "cargo/export/export-update";
    }

    /*
      url:/export/delete.do?id=02e1da04-43f8-42e1-a4c2-66e162c6f4a5
      作用： 删除选择的报运单，返回报运单列表页面
      参数： id
     */
    @RequestMapping("/delete")
    public String delete(String id){
        exportService.delete(id);
        return "redirect:/cargo/export/list.do";
    }


    /*
      url:/cargo/export/toView.do?id=dd63eb3c-6d4e-4a85-9c37-fcfda1998c1d
      作用： 查看报运单信息
      参数： id
    */
    @RequestMapping("/toView")
    public String toView(String id){
        Export export = exportService.findById(id);
        request.setAttribute("export",export);
        return "cargo/export/export-view";
    }

    /*
      url:/cargo/export/submit.do?id=dd63eb3c-6d4e-4a85-9c37-fcfda1998c1d
      作用： 更新报运单信息中的状态
      参数： id
    */
    @RequestMapping("/submit")
    public String submit(String id){
        Export export = exportService.findById(id);
        export.setState(1);
        exportService.update(export);
        return "redirect:/cargo/export/list.do";
    }

    /*
      url:/cargo/export/cancel.do?id=dd63eb3c-6d4e-4a85-9c37-fcfda1998c1d
      作用： 取消报运单信息中的状态
      参数： id
    */
    @RequestMapping("/cancel")
    public String cancel(String id){
        Export export = exportService.findById(id);
        export.setState(0);
        exportService.update(export);
        return "redirect:/cargo/export/list.do";
    }


    /*
      url:/cargo/export/exportE.do?id=a82cfe3c-c132-4f62-9101-132e8d54ad35
      作用： 提交报运单 到海关平台
      参数： 报运单的id
      返回值：得到海关平台的返回数据操作后，回到报运单列表页面
    */
    @RequestMapping("/exportE")
    public String exportE(String id){
        //1、得到报运单数据，封装到ExportVo
        Export export = exportService.findById(id);
        ExportVo exportVo = new ExportVo();
        BeanUtils.copyProperties(export,exportVo);
        //补充数据，设置exportId
        exportVo.setExportId(export.getId());

        //2、得到报运单下的所有商品，封装到exportProductVo
        ExportProductExample exportProductExample = new ExportProductExample();
        exportProductExample.createCriteria().andExportIdEqualTo(id);
        List<ExportProduct> exportProductList = exportProductService.findAll(exportProductExample);

        if (exportProductList!=null){
            for (ExportProduct exportProduct : exportProductList) {
                ExportProductVo exportProductVo = new ExportProductVo();
                BeanUtils.copyProperties(exportProduct,exportProductVo);
                //补充数据
                exportProductVo.setEid(exportVo.getId());
                //该报运货物所属的报运单id

                exportProductVo.setExportProductId(exportProduct.getId());

                exportVo.getProducts().add(exportProductVo);
            }
        }

        //3、发送给海关平台，调用服务
        //提交报运单
        WebClient.create("http://localhost:9090/ws/export/user").post(exportVo);

        //查看报运单审核结果方法
        ExportResult exportResult = WebClient.create("http://localhost:9090/ws/export/user/" + export.getId()).get(ExportResult.class);

        //4、得到海关平台返回的数据，更新报运单信息
        // 修改报运单的状态以及报运商品的税收
        exportService.updateByResult(exportResult);
        return "redirect:/cargo/export/list.do";
    }


    /*
      url:/cargo/export/exportPdf.do?id=a82cfe3c-c132-4f62-9101-132e8d54ad35
      作用： 下载报运单
      参数： 报运单id
      返回： 无返回，因为最后要是要下载
     */
    @RequestMapping("/exportPdf")
    @ResponseBody
    public void exportPdf(String id) throws Exception {
        //通知浏览器以文件下载的方式处理内容
        response.setHeader("content-disposition","attachment;filename=export.pdf");
        //1. 读取到jasper的文件的输入流
        InputStream inputStream = session.getServletContext().getResourceAsStream("/jasper/export.jasper");

        //2. 使用jasper文件输入流与数据结合，形参一个jasperPrint对象
        /*
            fillReport() , 把数据和jasperPrint对象结合形参一个jasperPrint对象
                参数一： japser文件的输入流
                参数二： 填充参数， 这里的参数是不遍历,所以放的数据是不需要被遍历的
                参数三： 需要遍历数据
         */
        //2.1根据报运单id查找报运单信息
        Export export = exportService.findById(id);
        //需要把export的对象转换为Map， key：属性名  value：属性值
        Map<String, Object> exportMap = BeanMapUtils.beanToMap(export);

        //2.2查找报运单下的报运商品信息
        ExportProductExample exportProductExample = new ExportProductExample();
        exportProductExample.createCriteria().andExportIdEqualTo(id);
        List<ExportProduct> exportProductList = exportProductService.findAll(exportProductExample);

        //把list的数据放入数据源中
        JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(exportProductList);


        JasperPrint jasperPrint = JasperFillManager.fillReport(inputStream, exportMap, dataSource);

        //3. 把jasperPrint对象输出，产生一个pdf文件
        JasperExportManager.exportReportToPdfStream(jasperPrint,response.getOutputStream());
    }

  /* @RequestMapping("/exportPdf")
    public void exportPdf(String id) throws Exception {
        //1. 读取到jasper的文件的输入流
        InputStream inputStream = session.getServletContext().getResourceAsStream("/jasper/test07_chart.jasper");

        //2. 使用jasper文件输入流与数据结合，形参一个jasperPrint对象
        *//*List<User> userList = new ArrayList<>();

       for (int j = 0; j < 5; j++) {
           for (int i = 0; i < 10; i++) {
               User user = new User();
               user.setUserName("小豆"+i);
               user.setEmail("1561224435@qq.com");
               user.setCompanyName("百万数据服务有限公司"+j);
               user.setDeptName("总裁部");
               userList.add(user);
           }
       }*//*

       List<Map<String,Object>> list = new ArrayList<>();
       for (int i = 0; i <5 ; i++) {
           Map<String,Object> map = new HashMap<>();
           map.put("title","李总传销第"+i+"号事业部");
           map.put("value",new Random().nextInt(100));
           list.add(map);
       }
       JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(list);

       JasperPrint jasperPrint = JasperFillManager.fillReport(inputStream, new HashMap<>(), dataSource);

        //3. 把jasperPrint对象输出，产生一个pdf文件
        JasperExportManager.exportReportToPdfStream(jasperPrint,response.getOutputStream());
    }*/
}
